package com.crea.web3jg.service;

import com.crea.web3jg.Web3jgApplication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.web3j.crypto.CipherException;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.WalletUtils;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameter;
import org.web3j.protocol.core.methods.request.Transaction;
import org.web3j.protocol.core.methods.response.EthGetBalance;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.exceptions.TransactionException;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.Transfer;
import org.web3j.utils.Convert;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;

/**
 * @program: sample-spring-blockchain
 * @description:
 * @author: wwd
 * @create: 2021-03-16 16:29
 **/
public class Wallet {
    private static final Logger LOGGER = LoggerFactory.getLogger(BlockchainService.class);
    private static final Logger log = LoggerFactory.getLogger(BlockchainService.class);
    private static Web3j  web3j;
    private static Credentials credentials;
    /*************创建一个钱包文件**************/
    public  static void creatAccount() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, CipherException, IOException {
        String walletFileName0="my_wallet";//文件名
        String walletFilePath0="H:\\blockchain\\web3jg";
        //钱包文件保持路径，请替换位自己的某文件夹路径

        walletFileName0 = WalletUtils.generateNewWalletFile("123456", new File(walletFilePath0), false);
        //WalletUtils.generateFullNewWalletFile("password1",new File(walleFilePath1));
        //WalletUtils.generateLightNewWalletFile("password2",new File(walleFilePath2));
        LOGGER.info("walletName: "+walletFileName0);
    }

    /********加载钱包文件**********/
    private static void loadWallet() throws IOException, CipherException {
        String walleFilePath="H:\\blockchain\\web3jg\\UTC--2021-03-17T06-15-22.347000000Z--704efc81b0f7ee176eedb433b29ac79001e1f12b.json";
        String passWord="123456";
        credentials = WalletUtils.loadCredentials(passWord, walleFilePath);
        String address = credentials.getAddress();
        BigInteger publicKey = credentials.getEcKeyPair().getPublicKey();
        BigInteger privateKey = credentials.getEcKeyPair().getPrivateKey();

        LOGGER.info("address="+address);
        LOGGER.info("public key="+publicKey);
        LOGGER.info("private key="+privateKey);

    }
    /*******连接以太坊客户端**************/
    private static  void conectETHclient() throws IOException {
        //连接方式1：使用infura 提供的客户端
//      web3j = Web3j.build(new HttpService("https://rinkeby.infura.io/zmd7VgRt9go0x6qlJ2Mk"));// TODO: 2018/4/10 token更改为自己的
        //连接方式2：使用本地客户端
        web3j = Web3j.build(new HttpService("http://192.168.30.123:8545"));
        //测试是否连接成功
        String web3ClientVersion = web3j.web3ClientVersion().send().getWeb3ClientVersion();
        LOGGER.info("version=" + web3ClientVersion);
    }


    /***********查询指定地址的余额***********/
    private static void getBlanceOf() throws IOException {
        if (web3j == null) return;
//        String address = "0x704efc81b0f7ee176eedb433b29ac79001e1f12b";//等待查询余额的地址
        String address =  "0x1a9076c5c6c6a6791142edfca9ea7ad050beabe1";
        //第二个参数：区块的参数，建议选最新区块
        EthGetBalance balance = web3j.ethGetBalance(address, DefaultBlockParameter.valueOf("latest")).send();
        //格式转化 wei-ether
        String blanceETH = Convert.fromWei(balance.getBalance().toString(), Convert.Unit.ETHER).toPlainString().concat(" ether");
        LOGGER.info(blanceETH);
    }

   /****************交易*****************/
    private static void transto() throws Exception {
        if (web3j == null) return;
        if (credentials == null) return;
        //开始发送0.01 =eth到指定地址
        String address_to = "0xfd6f51873ef4965e0cfebec22c80e0aeb9315769";
        TransactionReceipt send = Transfer.sendFunds(web3j, credentials, address_to, BigDecimal.ONE, Convert.Unit.KWEI).send();

//        TransactionReceipt send = Transfer.sendFunds(web3j, credentials, address_to, BigDecimal.ONE, Convert.Unit.FINNEY).send();

        LOGGER.info("Transaction complete:");
        LOGGER.info("trans hash=" + send.getTransactionHash());
        LOGGER.info("from :" + send.getFrom());
        LOGGER.info("to:" + send.getTo());
        LOGGER.info("gas used=" + send.getGasUsed());
        LOGGER.info("status: " + send.getStatus());
    }
    public static void main(String[] args) throws Exception {
//        creatAccount();
       loadWallet();
        conectETHclient();
        getBlanceOf();
        transto();
//        Web3j web3j = Web3j.build(new HttpService(
//                "http://192.168.30.123:8545"));  // FIXME: Enter your Infura token here;
//        log.info("Connected to Ethereum client version: "
//                + web3j.web3ClientVersion().send().getWeb3ClientVersion());
//
//        // We then need to load our Ethereum wallet file
//        // FIXME: Generate a new wallet file using the web3j command line tools https://docs.web3j.io/command_line.html
//        Credentials credentials =
//                WalletUtils.loadCredentials(
//                        "123",
//                        "H:\\blockchain\\web3jg\\UTC--2021-03-17T05-12-38.342547445Z--26c2876e2bed4d781c9edf14d3f15b807cfe11e5");
//        log.info("Credentials loaded");
//
//        // FIXME: Request some Ether for the Rinkeby test network at https://www.rinkeby.io/#faucet
//        log.info("Sending 1 Wei ("
//                + Convert.fromWei("1", Convert.Unit.ETHER).toPlainString() + " Ether)");
//        TransactionReceipt transferReceipt = Transfer.sendFunds(
//                web3j, credentials,
//                "0xfd6f51873ef4965e0cfebec22c80e0aeb9315769",  // you can put any address here
//                BigDecimal.ONE, Convert.Unit.WEI)  // 1 wei = 10^-18 Ether
//                .send();
//        log.info("Transaction complete, view it at https://rinkeby.etherscan.io/tx/"
//                + transferReceipt.getTransactionHash());
    }
}
